package com.minisoft.extractor;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

public class MethodExtractor {
    private Set<String> visitedClasses = new HashSet<>();

    public void extractMethods(Class<?> clazz, String methodName) throws Exception {
        visitedClasses.clear();
        extractMethodsHelper(clazz, methodName, "");
    }

    private void extractMethodsHelper(Class<?> clazz, String methodName, String indent) throws Exception {
        if (visitedClasses.contains(clazz.getName())) {
            return;
        }
        visitedClasses.add(clazz.getName());

        String classFilePath = clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
        String sourceFilePath = getSourceFilePath(clazz.getName(), classFilePath);

        System.out.println(indent + "class " + clazz.getSimpleName() + " {");

        try (BufferedReader reader = new BufferedReader(new FileReader(sourceFilePath))) {
            String line;
            boolean inMethod = false;
            while ((line = reader.readLine()) != null) {
                if (line.contains(methodName)) {
                    inMethod = true;
                }
                if (inMethod) {
                    System.out.println(indent + "    " + line);
                }
                if (inMethod && line.contains("{")) {
                    int openBraces = 1;
                    while (openBraces > 0 && (line = reader.readLine()) != null) {
                        System.out.println(indent + "    " + line);
                        if (line.contains("{")) {
                            openBraces++;
                        }
                        if (line.contains("}")) {
                            openBraces--;
                        }
                    }
                    inMethod = false;
                }
            }
        }

        for (Method method : clazz.getDeclaredMethods()) {
            if (!method.getName().equals(methodName)) {
                continue;
            }
            System.out.println(indent + "    ");
            System.out.println(indent + "    " + method);
            extractMethodsHelper(method.getReturnType(), methodName, indent + "    ");
        }

        System.out.println(indent + "}");
    }

    private String getSourceFilePath(String className, String classFilePath) {
        String sourceFilePath = classFilePath.replace("target/classes", "src/main/java");
        sourceFilePath = sourceFilePath.replace("/", File.separator);
        sourceFilePath = sourceFilePath.substring(1);
        sourceFilePath = sourceFilePath + className.replace(".", File.separator) + ".java";
        return sourceFilePath;
    }


}
